home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- GoldED API client example code, ©1995 Dietmar Eilert. Dice:
-
- dcc main.c -// -mRR -r -proto -2.0 -l tmsr.lib -l reqtoolssr.lib -o ram:dock
-
- Note: Compiling this code requires ToolManger includes & ToolManager linker
- libraries. ToolManager is ©1990-1995 Stefan Becker.
-
- The following example uses synchronous ARexx communication: Requests are
- PutMsg()'ed to GoldED's port, followed by a WaitPort() to get the editor's
- response. This works fine since we need no ARexx communication after the API
- link has been established. If there were ARexx communication AFTER the link has
- been established (i.e. after sending the 'API PORT=...' command to register
- with GoldED), we would have to use an asynchronous design beeing capable of
- answering incoming API messages while waiting for completion of ARexx requests
- sent to GoldED.
-
- ------------------------------------------------------------------------------
- */
-
- /// "includes"
-
- #define Prototype extern
-
- #include <exec/exec.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos/dos.h>
- #include <dos/rdargs.h>
- #include <intuition/intuition.h>
- #include <workbench/startup.h>
- #include <rexx/errors.h>
- #include <rexx/rxslib.h>
- #include <libraries/reqtools.h>
- #include <utility/tagitem.h>
- #include <clib/toolmanager_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/rexxsyslib_protos.h>
- #include <clib/reqtools_protos.h>
-
- #include "golded:api/include/golded.h"
-
- // ToolManager objects are a combination of action/image/sound:
- // Les objets ToolManager sont une combinaison d'objets action/image/son:
-
- struct tmTool {
-
- APTR exec;
- APTR icon;
- APTR sound;
- };
-
- struct Library *ReqToolsBase;
-
- Prototype void main(int, char **);
- Prototype void HandleAPI(void *, char *, struct TagItem *, UWORD, UWORD);
- Prototype ULONG *SendRexxCommand(char *, char *, struct MsgPort *, char *);
- Prototype char *xsprintf(char *, char *);
- Prototype struct TagItem *ReadConfig(char *, void *, char *, UWORD *, UWORD *);
-
- ///
- /// "main"
-
- void
- main(int argc, char **argv)
- {
- const char *version = "$VER: dock 1.6 (" __COMMODORE_DATE__ ")";
-
- struct RDArgs *rdArgs;
-
- ULONG args[] = { 0, 0 };
-
- if (rdArgs = ReadArgs("CONFIG,HOST/K/A", args, NULL)) {
-
- UBYTE *prefs;
- UWORD try;
- void *handle;
-
- prefs = args[0] ? (char *)args[0] : "progdir:dock.prefs";
-
- // wait for ToolManager startup
-
- for (try = 20; !(handle = AllocTMHandle()) && try; try--)
- Delay(10);
-
- if (handle) {
-
- struct TagItem *dock;
-
- UWORD dockX = ~0, dockY = ~0;
-
- if (dock = ReadConfig(prefs, handle, (char *)args[1], &dockX, &dockY))
- HandleAPI(handle, (char *)args[1], dock, dockX, dockY);
-
- FreeTMHandle(handle);
- }
- else
- puts("got no TM handle ?!");
-
- FreeArgs(rdArgs);
- }
- else
- puts("syntax error: dock [<config>] HOST=<host>");
-
- exit(0);
- }
-
- int
- wbmain(struct WBStartup *startup)
- {
- if (ReqToolsBase = OpenLibrary("reqtools.library", 37)) {
-
- rtEZRequestTags("No executable - to be used as API client", "OK", NULL, NULL, TAG_DONE);
-
- CloseLibrary(ReqToolsBase);
- }
- }
-
-
- ///
- /// "read config"
-
- /* -------------------------------- ReadConfig ---------------------------------
-
- Read config file. Return ready-to-use tag array for dock creation or NULL.
- Write dock screen position to <dockX>/<dockY>.
-
- */
-
- struct TagItem *
- ReadConfig(prefs, handle, host, dockX, dockY)
-
- void *handle;
- char *prefs, *host;
- UWORD *dockX, *dockY;
- {
- struct TagItem *dock = NULL;
-
- BPTR config;
-
- if (config = Open(prefs, MODE_OLDFILE)) {
-
- struct RDArgs *rdArgs;
-
- if (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) {
-
- static char buffer[256];
-
- UWORD columns, entries, orientation;
-
- columns = 1;
- orientation = 0;
- entries = 0;
-
- while (FGets(config, buffer, 255)) {
-
- char *cmd;
-
- for (strcat(buffer, "\12"), cmd = buffer; *cmd && (*cmd != ';'); ++cmd) {
-
- if ((*cmd != ' ') && (*cmd != 10)) {
-
- ULONG n, argArray[] = { 0, 0, 0, 0, 0, 0 };
-
- struct RDArgs *args;
-
- static struct parser { char *command; char *template; } parser[] = {
-
- "ADD", "COMMAND/K/A,AREXX/S,EXEC/S,DIR/K,OUTPUT/K,ICON/K/A",
- "DOCK", "X/N,Y/N,HORIZONTAL/S,COLUMNS/N",
- NULL
- };
-
- for (n = 0; parser[n].command; ++n) {
-
- if (!memcmp(cmd, parser[n].command, strlen(parser[n].command))) {
-
- cmd += strlen(parser[n].command);
-
- rdArgs->RDA_Source.CS_Buffer = cmd;
- rdArgs->RDA_Source.CS_Length = strlen(cmd);
- rdArgs->RDA_Source.CS_CurChr = 0;
- rdArgs->RDA_DAList = NULL;
- rdArgs->RDA_Buffer = NULL;
-
- if (args = ReadArgs(parser[n].template, argArray, rdArgs)) {
-
- if (n == 0) {
-
- char execName[8], iconName[8];
-
- struct TagItem iconTags[] = { TMOP_File, strdup((char *)argArray[5]), TMOP_Data, NULL, TAG_DONE };
-
- struct TagItem execTags[] = {
-
- TMOP_Command, xsprintf((char *)argArray[0], host),
- TMOP_ExecType, argArray[1] ? TMET_ARexx : TMET_CLI,
- TMOP_Stack, 8192,
- TMOP_CurrentDir, argArray[3] ? strdup((char *)argArray[3]) : NULL,
- TMOP_Output, argArray[4] ? strdup((char *)argArray[4]) : NULL,
- TAG_DONE
- };
-
- sprintf(execName, "e%ld", entries);
- sprintf(iconName, "i%ld", entries++);
-
- CreateTMObjectTagList(handle, strdup(execName), TMOBJTYPE_EXEC, execTags);
- CreateTMObjectTagList(handle, strdup(iconName), TMOBJTYPE_IMAGE, iconTags);
- }
-
- else if (n == 1) {
-
- if (argArray[0])
- *dockX = *(ULONG *)argArray[0];
-
- if (argArray[1])
- *dockY = *(ULONG *)argArray[1];
-
- if (argArray[2])
- orientation = 1;
-
- if (argArray[3])
- columns = *(ULONG *)argArray[3];
- }
-
- FreeArgs(args);
- }
- }
- }
-
- break;
- }
- }
-
- if (entries) {
-
- if (dock = (struct TagItem *)calloc((entries + 9) * sizeof(struct TagItem), 1)) {
-
- UWORD n;
-
- dock[0].ti_Tag = TMOP_PubScreen;
- dock[1].ti_Tag = TMOP_LeftEdge;
- dock[2].ti_Tag = TMOP_TopEdge;
- dock[3].ti_Tag = TMOP_Activated;
- dock[4].ti_Tag = TMOP_Centered;
- dock[5].ti_Tag = TMOP_Columns;
- dock[6].ti_Tag = TMOP_Vertical;
- dock[7].ti_Tag = TMOP_Text;
- dock[8].ti_Tag = TAG_DONE;
-
- dock[3].ti_Data = TRUE;
- dock[5].ti_Data = columns;
- dock[6].ti_Data = orientation;
-
- for (n = 0; n < entries; ++n) {
-
- struct tmTool *tool;
-
- if (tool = (struct tmTool *)calloc(sizeof(struct tmTool), 1)) {
-
- if ((tool->exec = calloc(8, 1)) && (tool->icon = calloc(8, 1))) {
-
- sprintf((char *)tool->exec, "e%ld", n);
- sprintf((char *)tool->icon, "i%ld", n);
-
- dock[8 + n].ti_Tag = TMOP_Tool;
- dock[8 + n].ti_Data = tool;
- }
- }
- }
- }
- }
-
- }
-
- FreeDosObject(DOS_RDARGS, rdArgs);
- }
-
- Close(config);
- }
- else
- puts("dock.prefs missing");
-
- return(dock);
- }
-
-
- ///
- /// "API management"
-
- /* --------------------------------- HandleAPI ---------------------------------
-
- Register with GoldED & handle incoming API messages.
-
- */
-
- void
- HandleAPI(handle, host, dock, dockX, dockY)
-
- struct TagItem *dock;
- char *host;
- void *handle;
- UWORD dockX, dockY;
- {
- struct MsgPort *replyPort;
-
- if (replyPort = CreateMsgPort()) {
-
- char command[255];
- ULONG *result;
-
- sprintf(command, "API PORT=%ld CLASS=%ld", replyPort, API_CLASS_ROOT | API_CLASS_SCREEN);
-
- if (result = SendRexxCommand(host, command, replyPort, NULL)) {
-
- if (*result == RC_OK) {
-
- BOOL active = TRUE;
-
- do {
-
- struct APIMessage *apiMsg, *nextMsg;
-
- // API messages might already have arrived since SendRexxCommand() only pulls one message of the port
-
- while (!(apiMsg = (struct APIMessage *)GetMsg(replyPort)))
- WaitPort(replyPort);
-
- do {
-
- for (nextMsg = apiMsg; nextMsg; nextMsg = nextMsg->api_Next) {
-
- if (nextMsg->api_State == API_STATE_NOTIFY) {
-
- switch (nextMsg->api_Class) {
-
- case API_CLASS_ROOT:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_DIE:
-
- active = FALSE;
-
- DeleteTMObject(handle, "dock1");
- break;
-
- case API_ACTION_INTRODUCE:
-
- static struct TagItem tags[] = {
-
- API_Client_Name, "dock",
- API_Client_Copyright, "©1995 Dietmar Eilert",
- API_Client_Purpose, "ToolManager dock for GoldED",
- TAG_DONE
- };
-
- nextMsg->api_Data = tags;
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
-
- break;
-
- case API_CLASS_SCREEN:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_HIDE:
-
- DeleteTMObject(handle, "dock1");
- break;
-
- case API_ACTION_SHOW:
-
- struct Screen *screen;
-
- if (screen = LockPubScreen(nextMsg->api_Global->F_ScrnName)) {
-
- dock[0].ti_Data = nextMsg->api_Global->F_ScrnName;
- dock[1].ti_Data = (dockX == ~0) ? screen->Width : dockX;
- dock[2].ti_Data = (dockY == ~0) ? screen->BarHeight + ((screen->BitMap.Depth == 1) ? 2 : 1) : dockY;
-
- UnlockPubScreen(NULL, screen);
- }
-
- CreateTMObjectTagList(handle, "dock1", TMOBJTYPE_DOCK, dock);
-
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
-
- ReplyMsg((struct Message *)apiMsg);
-
- } while (apiMsg = (struct APIMessage *)GetMsg(replyPort));
-
- } while (active);
- }
- }
-
- DeleteMsgPort(replyPort);
- }
- }
-
-
- ///
- /// "misc"
-
- /* --------------------------------- xsprintf ----------------------------------
-
- sprintf frontend (malloc buffer); limited to string insertion into string
-
- */
-
- char *
- xsprintf(mask, var)
-
- char *mask, *var;
- {
- char *buffer;
-
- if (buffer = malloc(strlen(mask) + strlen(var)))
- sprintf(buffer, mask, var);
-
- return(buffer);
- }
-
- ///
- /// "ARexx"
-
- /* ---------------------------------- SendRexxCommand -------------------------
-
- Send ARexx message & wait for answer. Return pointer to result or NULL.
-
- */
-
- ULONG *
- SendRexxCommand(port, cmd, replyPort, buffer)
-
- char *cmd, *port, *buffer;
- struct MsgPort *replyPort;
- {
- struct MsgPort *rexxport;
-
- Forbid();
-
- if (rexxport = FindPort(port)) {
-
- struct RexxMsg *rexxMsg, *answer;
-
- if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
-
- if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
-
- static ULONG result;
-
- rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
-
- PutMsg(rexxport, &rexxMsg->rm_Node);
-
- do {
-
- WaitPort(replyPort);
-
- if (answer = (struct RexxMsg *)GetMsg(replyPort))
- result = answer->rm_Result1;
-
- } while (!answer);
-
- Permit();
-
- if (answer->rm_Result1 == RC_OK) {
-
- if (answer->rm_Result2) {
-
- if (buffer)
- strcpy(buffer, (char *)answer->rm_Result2);
-
- DeleteArgstring((char *)answer->rm_Result2);
- }
- }
-
- DeleteArgstring((char *)ARG0(answer));
-
- DeleteRexxMsg(answer);
-
- return(&result);
- }
- }
- }
-
- Permit();
-
- return(NULL);
- }
-
- ///
-